home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-07 | 5.7 KB | 292 lines | [TEXT/MPS ] |
-
- #include "DaemonApp.h"
- #include "UFailure.h"
-
- #include <Events.h>
- #include <GestaltEqu.h>
- #include <Notification.h>
- #include <Desk.h>
-
- #include <String.h>
- #include <Strings.h>
-
- #if qDebug
- #include <StdIO.h>
- #endif
-
- static DaemonApp* gDaemon = nil;
-
- pascal void
- InitUDaemonApp(long stacksize)
- {
- static FailInfo pFi;
-
- CatchFailures(pFi, &TopLevelFail, &pFi);
-
- if (stacksize) SetApplLimit(GetApplLimit() - stacksize);
- FailMemError();
- MaxApplZone();
- }
-
- pascal void
- #if qDebug
- TopLevelFail(short e, long m, void* )
- #else
- TopLevelFail(short , long , void* )
- #endif
- {
- FailInfo fi;
-
- if (qDebug) {
- char str[255];
- sprintf(str, "TopLevelFail: error = %d, message = %d\n", e, m);
- DebugStr(CStr255(str));
- }
-
- if (fi.Try()) {
- if (gDaemon) delete gDaemon;
- fi.Success();
- }
-
- ExitToShell();
- }
-
- DaemonApp::DaemonApp()
- {
- fQuit = false;
-
- this->SetSleepValue(0x7FFFFFFF);
- this->SetEventMask(highLevelEventMask);
- this->SetMouseRgn(nil);
- this->SetEndWaitTime(3600);
-
- gDaemon = this;
- }
-
- DaemonApp::~DaemonApp()
- {
- if (fNoteList.First()) {
- if (qDebug) DebugStr("\pThere are some notes outstanding;g");
-
- long now = TickCount();
- while (fNoteList.First() && (TickCount() < now + fEndWait))
- WaitNextEvent(osMask, &fERecord, 60, nil);
- }
-
- if (qDebug && fNoteList.First()) DebugStr("\pThere were some left");
- }
-
- void
- DaemonApp::Initialize()
- {
- long aLong = 0;
-
- this->InitToolBox();
- this->InstallAEHandlers();
-
- GetCurrentProcess(&fPSN);
-
- fA5 = SetCurrentA5();
- }
-
- void
- DaemonApp::InitToolBox()
- {
- /* We are NOT initializing many managers. We're in the background, with no */
- /* face, we can't use windows or dialogs or menus. If you need to talk to the */
- /* user you can post a notification, or launch an application to communicate */
- /* Passing an AppleEvent in the launchapplication trap could do the */
- /* communication for you. */
-
- /* The technote on BOA's says to call InitGraf to use AppleEvents, who am I
- to question…
- */
-
- InitGraf(&qd.thePort);
- }
-
- void
- DaemonApp::Run()
- {
- while (fQuit == false) {
- WaitNextEvent(fEventMask, &fERecord, fMySleep, fMouseRgn);
-
- switch (fERecord.what) {
- case nullEvent:
- this->DoNull();
- break;
-
- case kHighLevelEvent:
- this->DoHighLevel(&fERecord);
- break;
- }
- }
- }
-
- void
- DaemonApp::DoQuit()
- {
- fQuit = true;
- WakeUpProcess(&fPSN);
- }
-
- void
- DaemonApp::InstallAEHandlers()
- {
- FailInfo fi;
-
- if (fi.Try()) {
- FailOSErr(AEInstallEventHandler(kCoreEventClass, kAEOpenApplication,
- (EventHandlerProcPtr) DoAEOpenApplication, (long) this, false));
-
- FailOSErr(AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
- (EventHandlerProcPtr) DoAEOpenDocuments, (long) this, false));
-
- FailOSErr(AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
- (EventHandlerProcPtr) DoAEPrintDocuments, (long) this, false));
-
- FailOSErr(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication,
- (EventHandlerProcPtr) DoAEQuitApplication, (long) this, false));
-
- fi.Success();
- }
- else {
- if (qDebug) DebugStr("\pInstallAEHandlers failed");
- fi.ReSignal();
- }
- }
-
- void
- DaemonApp::PostNotification(char* str)
- {
- FailInfo fi;
-
- if (fi.Try()) {
- NMRec* theNote = (NMRec*) NewPtrClear(sizeof(NMRec));
- FailMemError();
-
- Ptr string = NewPtr(strlen(str) + 1);
- FailMemError();
-
- BlockMove(str, string, strlen(str) + 1);
- c2pstr(string);
-
- theNote->qType = nmType;
- theNote->nmMark = 0;
- theNote->nmIcon = nil;
- theNote->nmSound = nil;
- theNote->nmStr = (Str255) string;
- theNote->nmResp = &NMResponseProc;
- theNote->nmRefCon = (long) this;
-
- FailOSErr(NMInstall(theNote));
-
- NoteItem* nu = new NoteItem(theNote);
- FailNIL(nu);
- fNoteList.PutOn(nu);
-
- fi.Success();
- }
- else {
- if (qDebug) DebugStr("\pPostNotification failed");
- fi.ReSignal();
- }
- }
-
- /* The NoteItem destructor will call this routine automatically when things are
- being cleaned up. This is nice for clean up, but needs to be kept in mind
- for normal removal - if we just 'delete' the object associated with the NMRec,
- its destructor will come back here. This is Bad. Thats why the nmResp field
- gets zeroed. We also need to set up A5 because the destructor is virtual.
- */
- pascal void
- NMResponseProc(NMRec* theNote)
- {
- NoteItem* oldItem;
- DaemonApp* daemon;
- long oldA5;
-
- daemon = (DaemonApp*) theNote->nmRefCon;
- oldA5 = SetA5(daemon->fA5);
-
- NMRemove(theNote);
- theNote->nmResp = nil;
-
- oldItem = daemon->fNoteList.GetItem(theNote);
- if (oldItem) {
- daemon->fNoteList.TakeOff(oldItem);
- delete oldItem;
- }
-
- DisposePtr((Ptr) theNote->nmStr);
- DisposePtr((Ptr) theNote);
-
- SetA5(oldA5);
- }
-
- NoteItem*
- NoteList::GetItem(NMRec* note)
- {
- NoteItem* it = (NoteItem*) this->First();
-
- while (it && (note != it->fNote))
- it = (NoteItem*) it->fNext;
-
- return it;
- }
-
- void
- DaemonApp::DoHighLevel(EventRecord* AERecord)
- {
- FailInfo fi;
-
- if (fi.Try()) {
- FailOSErr(AEProcessAppleEvent(AERecord));
- fi.Success();
- }
- else {
- if (qDebug) {
- long evtID;
- long evtClass;
-
- char str[128];
-
- evtID = AERecord->message;
- evtClass = *((long*) &AERecord->where);
-
- sprintf(str, "DoHighLevel failed: class = %p, id = %p, err = %d",
- evtClass, evtID, fi.error);
-
- DebugStr(CStr255(str));
- }
-
- fi.ReSignal();
- }
- }
-
- pascal OSErr
- DoAEOpenApplication(AppleEvent* /*messagein*/, AppleEvent* /*reply*/, long /*refIn*/)
- {
- return noErr;
- }
-
- pascal OSErr
- DoAEOpenDocuments(AppleEvent* /*messagein*/, AppleEvent* /*reply*/, long /*refIn*/)
- {
- return errAEEventNotHandled;
- }
-
- pascal OSErr
- DoAEPrintDocuments(AppleEvent* /*messagein*/, AppleEvent* /*reply*/, long /*refIn*/)
- {
- return errAEEventNotHandled;
- }
-
- pascal OSErr
- DoAEQuitApplication(AppleEvent* /*messagein*/, AppleEvent* /*reply*/, long refIn)
- {
- ((DaemonApp*) refIn)->DoQuit();
-
- return noErr;
- }
-